package gu.sql2java;

import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;

import gu.sql2java.exception.RuntimeDaoException;

public interface SqlRunner {

	/**
	 * Load all the elements using a SQL statement specifying a list of fields to be retrieved.
	 * @param sql the SQL statement for retrieving
	 * @param argList the arguments to use fill given prepared statement,may be null
	 * @return an list of BaseBean bean, or empty list if no row return
	 * @throws RuntimeDaoException 
	 */
	List<BaseBean> runSqlAsList(String sql, Object... argList) throws RuntimeDaoException;

	/**
	 * Load all the elements using a SQL statement specifying a list of fields to be retrieved.
	 * @param targetTypes map of target type for column name or null
	 * @param sql the SQL statement for retrieving
	 * @param argList the arguments to use fill given prepared statement,may be null
	 * @return an list of row values map, or empty list if no row return
	 * @throws RuntimeDaoException 
	 */
	List<Map<String, Object>> runSqlForMap(Map<String, Class<?>> targetTypes, String sql, Object... argList)
			throws RuntimeDaoException;

	/**
	 * Load all the elements using a SQL statement specifying a fields to be retrieved.
	 * @param targetType target type for column  or null
	 * @param sql the SQL statement for retrieving
	 * @param argList the arguments to use fill given prepared statement,may be null
	 * @return an list of row values , or empty list if no row return
	 * @throws RuntimeDaoException 
	 */
	<T> List<T> runSqlAsList(Class<T> targetType, String sql, Object... argList) throws RuntimeDaoException;

	/**
	 * Load all the elements using a SQL statement specifying a row of a field to be retrieved.
	 * @param targetType target type for column or null
	 * @param sql the SQL statement for retrieving
	 * @param argList the arguments to use fill given prepared statement,may be null
	 * @return SQL statement return value
	 * @throws RuntimeDaoException
	 */
	<T> T runSqlForValue(Class<T> targetType, String sql, Object... argList) throws RuntimeDaoException;

	/**
	 * Run {@code Callable<T>} as a transaction.<br>
	 * all exceptions but {@code SQLException} threw by {@code Callable<T>} is wrapped into {@code RuntimeException}<br>
	 * throw {@code NullPointerException} if {@code fun} be {@code null}<br>
	 * @param <T>  type of return result
	 * @param fun
	 * @return return T object
	 * @throws RuntimeDaoException
	 */
	<T> T runAsTransaction(Callable<T> fun) throws RuntimeDaoException;

	/**
	 * Run {@code Runnable} as a transaction.no return
	 * @param fun
	 * @see #runAsTransaction(Runnable)
	 * @throws RuntimeDaoException
	 */
	void runAsTransaction(Runnable fun) throws RuntimeDaoException;

	/**
	 *  run a SQL statement as {@link java.sql.PreparedStatement}
	 * @param sql the SQL statement for running
	 * @param argList the arguments to use fill given prepared statement,may be null
	 * @return see  {@link java.sql.Statement#execute()}
	 */
	boolean runSql(String sql, Object[] argList);

	/**
	 *  run a SQL statement as {@link java.sql.Statement}. 
	 *  which may be an INSERT, UPDATE, or DELETE statement or an SQL statement that returns nothing, 
	 *  such as an SQL DDL statement. 
	 *  
	 * @param sql the SQL statement for running
	 * @return see  {@link java.sql.Statement#executeUpdate(String sql)}
	 */
	int runSql(String sql);

	/**
	 * run a {@code Callable<T>} in Disable PageHelper environment
	 * @param <T>  type of return result
	 * @param fun
	 * @return return T object
	 * @throws RuntimeDaoException
	 * @since 3.11.1
	 */
	public <T> T runWithNoPage(Callable<T> fun) throws RuntimeDaoException;

	/**
	 * run a {@code Runnable} in Disable PageHelper environment
	 * @param fun
	 * @throws RuntimeDaoException
	 * @since 3.11.1
	 */
	void runWithNoPage(Runnable fun) throws RuntimeDaoException;
    /**
     * compute row count of SQL statement
     * @param where
     * @throws RuntimeDaoException 
     * @since 3.15.4
     */
    long rowCountOf(String sql) throws RuntimeDaoException;

}